;**************************************************************
;*
;*             BITROWZ Monitor Program Version 0.1
;*
;**************************************************************
; 1. Initialize the peripherals, ACIA, VDP, CompactFlash, etc.
;
; 2.Load the bootloader.bin from LBA0 of compact flash into
; RAM address 0x8000, then jump to.

; Address of bootloader.bin resides
DMAAD       equ 0x8000
STACK       equ 0xFFFF

;ACIA registers
SIO_REG     equ 0xDE
SIO_DATA    equ 0xDF

; CF registers
CF_BASE     equ 0x98	    ;BASE ADDRESS OF PRIMARY IDE CONTROLLER
CF_REG0	    equ	CF_BASE + 0	;DATA PORT
CF_REG1	    equ	CF_BASE + 1	;READ: ERROR CODE, WRITE: FEATURE
CF_REG2	    equ	CF_BASE + 2	;NUMBER OF SECTORS TO TRANSFER
CF_REG3	    equ	CF_BASE + 3	;SECTOR ADDRESS LBA 0 [0:7]
CF_REG4	    equ	CF_BASE + 4	;SECTOR ADDRESS LBA 1 [8:15]
CF_REG5	    equ	CF_BASE + 5	;SECTOR ADDRESS LBA 2 [16:23]
CF_REG6	    equ	CF_BASE + 6	;SECTOR ADDRESS LBA 3 [24:27 (LSB)]
CF_REG7	    equ	CF_BASE + 7	;READ: STATUS, WRITE: COMMAND

    org 0x0000
    jp      entry

;------------------------------------------------------------------------------
; Initialize ACIA
;------------------------------------------------------------------------------
acia_init:
    ld      a,0x17          ;MB68B50 reset
    out     (SIO_REG),a
    ld      a,0x16
    out     (SIO_REG),a    ;MB68B50 set bardrate to 115200
    ret

;------------------------------------------------------------------------------
; Print message to ACIA.
;------------------------------------------------------------------------------
acia_print:
    ld      a,(hl)
    inc     hl
    or      a
    ret     z                   ;return if encountered 0
    ld      c,a
acia_print_wait:
    in      a,(SIO_REG)         ;wait until write is ready
    and     0x02                ;mask out TDRE bit
    jp      z,acia_print_wait
    ld      a,c
    out     (SIO_DATA),a
    jp      acia_print

;------------------------------------------------------------------------------
; Dump memory to ACIA.
; hl: memory address
; b:  number of bytes
;------------------------------------------------------------------------------
acia_dump:
    ld      a,(hl)
    inc     hl
    ld      c,a
acia_dump_wait:
    in      a,(SIO_REG)         ;wait until write is ready
    and     0x02                ;mask out TDRE bit
    jp      z,acia_dump_wait
    ld      a,c
    out     (SIO_DATA),a
    dec     de
    ld      a,d
    or      e
    jp      nz,acia_dump
    ret

;------------------------------------------------------------------------------
; Wait until CF is not busy.
;------------------------------------------------------------------------------
cf_wait:
    in      a,(CF_REG7)         ;read status
    and     0x80                ;mask out BSY bit
    jp      nz,cf_wait          ;wait until BSY is cleared
    ret

;------------------------------------------------------------------------------
; Entry point
;------------------------------------------------------------------------------
entry:
    di
    ld      sp,STACK            ;setup stack area
    call    acia_init           ;initialize ACIA
    ld      hl,welcome_msg      ;print welcome message
    call    acia_print     

;------------------------------------------------------------------------------
; Initialize CompactFlash.
;------------------------------------------------------------------------------
cf_init:
    ld      a,0x04                  ;reset
    out     (CF_REG7),a
    call    cf_wait
    ld      a,0xE0                  ;LBA3=0, master, mode=LBA
    out	    (CF_REG6),a            
    ld      a,0x01                  ;8-bit transfers
    out	    (CF_REG1),a
    ld      a,0xEF                  ;set feature command
    out	    (CF_REG7),a                
    call    cf_wait
cf_ready:                           ;check if device is ready to receive read/write/seek commands
    in      a,(CF_REG7)
    and     0x40                    ;mask out DRDY bit
    jp      z,cf_ready
    ld      a,1                     ;set number of sectors to transfer
    out     (CF_REG2),a
    ld      a,0                     ;LBA bits 0~7
    out     (CF_REG3),a
    ld      a,0                     ;LBA bits 8~15
    out     (CF_REG4),a
    ld      a,0                     ;LBA bits 16~23
    out     (CF_REG5),a
    ld      a,0x20			        ;read command
	out	    (CF_REG7),a
    call    cf_wait
    ld      hl,DMAAD
cf_read:                            ;read sectors
    in      a,(CF_REG0)             ;get data
    ld      (hl),a                  ;copy to memory
	inc	    hl
    in      a,(CF_REG7)			    ;check if data transfer is ready
	and	    0x08                    ;mask out DRQ bit
    jp      nz,cf_read              ;read next
    in      a,(CF_REG7)			    ;check status
	and	    0x01                    ;mask out ERR bit
    jp      nz,cf_read_error
cf_read_success:                    ;read complete
    ld      hl, success_msg       
    call    acia_print
    jp      DMAAD                   ;jump to beginning of top 32K memory
    halt
cf_read_error:                      ;read error
    ld hl, error_msg       
    call acia_print
    halt

welcome_msg:
    defb "Bitrowz Monitor Program  V0.1\n", 0

error_msg:
    defb "Load bootloader.bin error!\n", 0

success_msg:
    defb "Load bootloader.bin...\n", 0